package cn.tedu.java.thread;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

/**
 * JAVA中构建线程池推荐使用ThreadPoolExecutor对象，
 * 所有的池对象默认都会用到一中享元设计模式，目的是
 * 实现对象的复用。减少对象在内存中的创建和销毁过程。
 *
 * //线程池执行任务的逻辑
 * https://www.processon.com/view/link/63982f53e0b34d62e0be5462
 * https://www.processon.com/view/link/6398300c7d9c084a6a421005
 *
 * public ThreadPoolExecutor(int corePoolSize,
 *                           int maximumPoolSize,
 *                           long keepAliveTime,
 *                           TimeUnit unit,
 *                           BlockingQueue<Runnable> workQueue,
 *                           ThreadFactory threadFactory,
 *                           RejectedExecutionHandler handler)
 */
public class ThreadPoolTests {
    /**核心线程数*/
    static int corePoolSize=2;

    /**最大线程数*/
    static int maximumPoolSize=3;

    /**线程空闲时间(线程空闲多长时间以后可以被释放)*/
    static long keepAliveTime=60;

    /**时间单位*/
    static TimeUnit unit=TimeUnit.SECONDS;

    /**阻塞队列(存储任务的一个队列，任务的类型为Runnable类型)*/
    static BlockingQueue<Runnable> workQueue=
            new ArrayBlockingQueue<>(1);

    /**拒绝策略（这里指定由调用者线程来执行）*/
    static RejectedExecutionHandler handler=
            new ThreadPoolExecutor.CallerRunsPolicy();


    private static final AtomicLong  poolNumber =
                             new AtomicLong(1);
    /**构建一个线程工厂对象(实际项目中推荐自己创建线程工厂自己设计线程名)*/
    static ThreadFactory threadFactory=new ThreadFactory() {
        private String namePrefix="service-thread->";
        @Override
        public Thread newThread(Runnable r) {
            return new Thread(r,namePrefix+poolNumber.getAndIncrement());
        }
    };

    public static void main(String[] args) {

       //1.构建一个线程池对象(初始状态池中没有线程)
        ThreadPoolExecutor poolExecutor=
                new ThreadPoolExecutor(corePoolSize,
                                       maximumPoolSize,
                                       keepAliveTime,
                                       unit,
                                       workQueue,
                                       threadFactory,
                                       handler);
        //2.通过池中的线程执行任务(提交任务)
        poolExecutor.execute(new Runnable() {//这里的Runnable对象表示任务对象
            @Override
            public void run() {//一旦线程获取了cpu就会执行这里的run方法
                String tName=Thread.currentThread().getName();
                System.out.println(tName+"->execute task01");
                try{Thread.sleep(5000);}catch (Exception e){}
            }
        });
        poolExecutor.execute(new Runnable() {
            @Override
            public void run() {//一旦线程获取了cpu就会执行这里的run方法
                String tName=Thread.currentThread().getName();
                System.out.println(tName+"->execute task02");
                try{Thread.sleep(5000);}catch (Exception e){}
            }
        });
        poolExecutor.execute(new Runnable() {
            @Override
            public void run() {//一旦线程获取了cpu就会执行这里的run方法
                String tName=Thread.currentThread().getName();
                System.out.println(tName+"->execute task03");
                try{Thread.sleep(5000);}catch (Exception e){}
            }
        });
        poolExecutor.execute(new Runnable() {
            @Override
            public void run() {//一旦线程获取了cpu就会执行这里的run方法
                String tName=Thread.currentThread().getName();
                System.out.println(tName+"->execute task04");
                try{Thread.sleep(5000);}catch (Exception e){}
            }
        });
        poolExecutor.execute(new Runnable() {
            @Override
            public void run() {//一旦线程获取了cpu就会执行这里的run方法
                String tName=Thread.currentThread().getName();
                System.out.println(tName+"->execute task05");
                try{Thread.sleep(5000);}catch (Exception e){}
            }
        });
        //关闭池对象(将来是服务停止时)
        poolExecutor.shutdown();
    }
}
